package com.imut.lagain.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imut.lagain.entity.FinalPassword;
import com.imut.lagain.repository.FinalPasswordRepository;
import com.imut.lagain.service.IFinalPasswordService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * 最终密码服务实现类
 * 提供密码管理相关的业务逻辑
 */
@Service
@RequiredArgsConstructor
@Transactional
public class FinalPasswordServiceImpl extends ServiceImpl<FinalPasswordRepository, FinalPassword> implements IFinalPasswordService {
    private static final Logger log = LoggerFactory.getLogger(FinalPasswordServiceImpl.class);

    
    private final PasswordEncoder passwordEncoder;
    
    /**
     * 获取当前激活的密码
     * @return 当前激活的密码
     */
    @Transactional(readOnly = true)
    public FinalPassword getCurrentActivePassword() {
        return baseMapper.findCurrentActivePassword();
    }
    
    /**
     * 获取所有激活的密码列表
     * @return 激活的密码列表
     */
    @Transactional(readOnly = true)
    public List<FinalPassword> getAllActivePasswords() {
        return baseMapper.findAllActivePasswords();
    }
    
    /**
     * 根据密码值查询（用于验证）
     * @param passwordValue 密码值
     * @return 密码信息
     */
    @Transactional(readOnly = true)
    public FinalPassword getPasswordByValue(String passwordValue) {
        if (!StringUtils.hasText(passwordValue)) {
            return null;
        }
        return baseMapper.findByPasswordValue(passwordValue);
    }
    
    /**
     * 根据激活状态分页查询
     * @param isActive 是否激活
     * @param page 分页参数
     * @return 密码分页列表
     */
    @Transactional(readOnly = true)
    public IPage<FinalPassword> getPasswordsByActiveStatus(Boolean isActive, Page<FinalPassword> page) {
        return baseMapper.findByActiveStatus(isActive, page);
    }
    
    /**
     * 根据创建时间范围查询
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param page 分页参数
     * @return 密码分页列表
     */
    @Transactional(readOnly = true)
    public IPage<FinalPassword> getPasswordsByCreateTimeBetween(LocalDateTime startTime, LocalDateTime endTime, Page<FinalPassword> page) {
        if (startTime == null || endTime == null) {
            return new Page<>();
        }
        return baseMapper.findByCreateTimeBetweenWithPage(startTime, endTime, page);
    }
    
    /**
     * 分页查询所有密码
     * @param page 分页参数
     * @return 密码分页列表
     */
    @Transactional(readOnly = true)
    public IPage<FinalPassword> page(Page<FinalPassword> page) {
        return baseMapper.selectPage(page, null);
    }
    
    /**
     * 统计激活密码数量
     * @return 激活密码数量
     */
    @Transactional(readOnly = true)
    public Long countActivePasswords() {
        return baseMapper.countActivePasswords();
    }
    
    /**
     * 统计总密码数量
     * @return 总密码数量
     */
    @Transactional(readOnly = true)
    public Long countTotalPasswords() {
        return baseMapper.countTotalPasswords();
    }
    
    /**
     * 创建新密码
     * @param passwordValue 密码值
     * @param description 描述
     * @param isActive 是否激活
     * @return 创建的密码
     */
    public FinalPassword createPassword(String passwordValue, String description, Boolean isActive) {
        if (!StringUtils.hasText(passwordValue)) {
            return null;
        }
        if (passwordExists(passwordValue)) {
            log.warn("Password already exists: {}", passwordValue);
            return null;
        }
        
        FinalPassword password = new FinalPassword();
        password.setPassword(passwordEncoder.encode(passwordValue));
        password.setDescription(description);
        password.setIsActive(isActive != null ? isActive : false);
        password.setCreateTime(LocalDateTime.now());
        password.setUpdateTime(LocalDateTime.now());
        
        boolean saved = this.save(password);
        if (saved) {
            log.info("Created new password with ID: {}", password.getId());
            return password;
        } else {
            log.error("Failed to create password");
            return null;
        }
    }
    
    /**
     * 更新密码激活状态
     * @param passwordId 密码ID
     * @param isActive 是否激活
     * @return 是否更新成功
     */
    public boolean updatePasswordActiveStatus(Long passwordId, Boolean isActive) {
        if (passwordId == null || isActive == null) {
            return false;
        }
        int result = baseMapper.updateActiveStatus(passwordId, isActive);
        if (result > 0) {
            return true;
        }
        return false;
    }
    
    /**
     * 停用所有密码
     * @return 停用的密码数量
     */
    public int deactivateAllPasswords() {
        int result = baseMapper.deactivateAllPasswords();
        return result;
    }
    
    /**
     * 根据描述模糊查询
     * @param description 描述关键字
     * @param page 分页参数
     * @return 密码分页列表
     */
    @Transactional(readOnly = true)
    public IPage<FinalPassword> searchPasswordsByDescription(String description, Page<FinalPassword> page) {
        if (!StringUtils.hasText(description)) {
            return new Page<>();
        }
        return baseMapper.findByDescriptionLike(description, page);
    }
    
    /**
     * 检查密码是否存在
     * @param passwordValue 密码值
     * @return 是否存在
     */
    @Transactional(readOnly = true)
    public boolean passwordExists(String passwordValue) {
        if (!StringUtils.hasText(passwordValue)) {
            return false;
        }
        return baseMapper.existsByPasswordValue(passwordValue);
    }
    
    /**
     * 获取最新创建的密码
     * @return 最新创建的密码
     */
    @Transactional(readOnly = true)
    public FinalPassword getLatestCreatedPassword() {
        return baseMapper.findLatestCreatedPassword();
    }
    
    /**
     * 获取最新更新的密码
     * @return 最新更新的密码
     */
    @Transactional(readOnly = true)
    public FinalPassword getLatestUpdatedPassword() {
        return baseMapper.findLatestUpdatedPassword();
    }
    
    /**
     * 验证密码
     * @param rawPassword 原始密码
     * @param encodedPassword 加密后的密码
     * @return 是否匹配
     */
    @Transactional(readOnly = true)
    public boolean verifyPassword(String rawPassword, String encodedPassword) {
        if (!StringUtils.hasText(rawPassword) || !StringUtils.hasText(encodedPassword)) {
            return false;
        }
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }
    
    /**
     * 验证密码是否为当前激活密码
     * @param rawPassword 原始密码
     * @return 是否为当前激活密码
     */
    @Transactional(readOnly = true)
    public boolean verifyCurrentPassword(String rawPassword) {
        if (!StringUtils.hasText(rawPassword)) {
            return false;
        }
        
        FinalPassword currentPassword = getCurrentActivePassword();
        if (currentPassword == null) {
            return false;
        }
        
        return verifyPassword(rawPassword, currentPassword.getPassword());
    }
    
    /**
     * 验证密码
     * @param passwordValue 密码值
     * @return 是否为有效的激活密码
     */
    @Transactional(readOnly = true)
    public boolean validatePassword(String passwordValue) {
        return verifyCurrentPassword(passwordValue);
    }
    
    /**
     * 激活指定密码并停用其他所有密码
     * @param passwordId 要激活的密码ID
     * @return 是否操作成功
     */
    public boolean activatePasswordExclusively(Long passwordId) {
        if (passwordId == null) {
            return false;
        }
        deactivateAllPasswords();
        boolean result = updatePasswordActiveStatus(passwordId, true);
        if (result) {
        }
        return result;
    }
    
    /**
     * 生成随机密码
     * @param length 密码长度
     * @return 随机密码
     */
    public String generateRandomPassword(int length) {
        if (length <= 0) {
            length = 12; // 默认长度
        }
        
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
        StringBuilder password = new StringBuilder();
        
        for (int i = 0; i < length; i++) {
            int index = (int) (Math.random() * chars.length());
            password.append(chars.charAt(index));
        }
        
        return password.toString();
    }
    
    /**
     * 生成UUID密码
     * @return UUID密码
     */
    public String generateUUIDPassword() {
        return UUID.randomUUID().toString().replace("-", "");
    }
    
    /**
     * 验证当前密码
     * @param password 要验证的密码
     * @return 是否验证成功
     */
    public boolean validateCurrentPassword(String password) {
        if (!StringUtils.hasText(password)) {
            return false;
        }
        FinalPassword currentPassword = baseMapper.findCurrentActivePassword();
        return currentPassword != null && currentPassword.getPassword().equals(password);
    }
    
    /**
     * 更新密码信息
     * @param password 密码信息
     * @return 是否更新成功
     */
    public boolean updatePassword(FinalPassword password) {
        if (password == null || password.getId() == null) {
            return false;
        }
        password.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(password);
        if (result) {
            log.info("Updated password: {}", password.getId());
        }
        return result;
    }
    
    /**
     * 删除密码
     * @param passwordId 密码ID
     * @return 是否删除成功
     */
    public boolean deletePassword(Long passwordId) {
        if (passwordId == null) {
            return false;
        }
        boolean result = this.removeById(passwordId);
        if (result) {
        }
        return result;
    }
    
    /**
     * 生成UUID密码
     * @return 生成的密码
     */
    public FinalPassword generateUuidPassword() {
        String uuid = java.util.UUID.randomUUID().toString().replace("-", "");
        String description = "系统生成的UUID密码 - " + LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return createPassword(uuid, description, true);
    }
}

